package com.longcai.cm.pay.wx;

import com.alibaba.fastjson.JSON;
import com.longcai.cm.common.constant.DomainConfig;
import com.longcai.cm.pay.wx.domain.WxOrderParam;
import com.longcai.cm.pay.wx.domain.WxRefundParam;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.service.payments.app.AppService;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.CloseOrderRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayResponse;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;

import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author libingxing
 */
public class WxPayApp {

    public static String createOrderApp(WxOrderParam param) {
        Config config = new RSAAutoCertificateConfig.Builder()
                .merchantId(WxPayConstants.MERCHANT_ID_APP)
                .privateKeyFromPath(WxPayConstants.PRIVATE_KEY_APP)
                .merchantSerialNumber(WxPayConstants.MERCHANT_SERIAL_NUMBER_APP)
                .apiV3Key(WxPayConstants.API_V3_KEY_APP)
                .build();
        final AppService appService = new AppService.Builder().config(config).build();
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(param.getAmount());
        request.setAmount(amount);
        request.setAttach(param.getAttach());
        request.setAppid(WxPayConstants.APP_ID_APP);
        request.setMchid(WxPayConstants.MERCHANT_ID_APP);
        request.setDescription(param.getDescription());
        request.setNotifyUrl(DomainConfig.LOCALHOST + param.getNotifyUrl());
        request.setOutTradeNo(param.getOrderNum());
        // 调用下单方法，得到应答
        PrepayResponse response = appService.prepay(request);

        Map<String, String> map = new LinkedHashMap<>(7);
        map.put("appId", WxPayConstants.APP_ID_APP);
        map.put("timeStamp", System.currentTimeMillis() / 1000 + "");
        map.put("nonceStr", WXPayUtil.generateNonceStr());
        map.put("prepayid", response.getPrepayId());
        final String sign = WXPayUtil.getPreSignApp(map);
        map.put("sign", sign);
        map.put("partnerid", WxPayConstants.MERCHANT_ID_APP);
        map.put("package", "Sign=WXPay");
        return JSON.toJSONString(map);
    }

    public static void closeOrder(String orderNum) {
        Config config = new RSAAutoCertificateConfig.Builder()
                .merchantId(WxPayConstants.MERCHANT_ID_APP)
                .privateKeyFromPath(WxPayConstants.PRIVATE_KEY_APP)
                .merchantSerialNumber(WxPayConstants.MERCHANT_SERIAL_NUMBER_APP)
                .apiV3Key(WxPayConstants.API_V3_KEY_APP)
                .build();
        final AppService appService = new AppService.Builder().config(config).build();
        CloseOrderRequest request = new CloseOrderRequest();
        request.setOutTradeNo(orderNum);
        request.setMchid(WxPayConstants.PRIVATE_KEY_APP);
        appService.closeOrder(request);
    }

    public static String orderRefundApp(WxRefundParam param) {
        Config config = new RSAAutoCertificateConfig.Builder()
                .merchantId(WxPayConstants.MERCHANT_ID_APP)
                .privateKeyFromPath(WxPayConstants.PRIVATE_KEY_APP)
                .merchantSerialNumber(WxPayConstants.MERCHANT_SERIAL_NUMBER_APP)
                .apiV3Key(WxPayConstants.API_V3_KEY_APP)
                .build();
        final RefundService refundService = new RefundService.Builder().config(config).build();
        CreateRequest request = new CreateRequest();
        AmountReq amount = new AmountReq();
        amount.setTotal(param.getTotal().multiply(new BigDecimal("100")).longValue());
        amount.setRefund(param.getRefund().multiply(new BigDecimal("100")).longValue());
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setOutTradeNo(param.getOrderNum());
        request.setOutRefundNo(param.getRefundId());
        // 调用下单方法，得到应答
        final Refund refund = refundService.create(request);
        return WXPayUtil.convertRefundStatus(refund.getStatus().name());
    }

    public static NotificationConfig getNotificationConfig() {
        return new RSAAutoCertificateConfig.Builder()
                .merchantId(WxPayConstants.MERCHANT_ID_APP)
                .privateKeyFromPath(WxPayConstants.PRIVATE_KEY_APP)
                .merchantSerialNumber(WxPayConstants.MERCHANT_SERIAL_NUMBER_APP)
                .apiV3Key(WxPayConstants.API_V3_KEY_APP)
                .build();
    }

}
